package org.diy.traffic.sources;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.diy.traffic.updates.TrafficUpdate;
import org.w3c.dom.NodeList;

/**
 * This class represents a FeedSource based on an RSS-formatted feed. It handles all the parsing for
 * RSS-formatted XML documents.
 * @author Dan Greenblatt
 *
 */
public class RSSFeedSource extends FeedSource {

	/**
	 * RSSFeedSource constructor, uses the default update frequency
	 * @param unique_name A unique String value to represent this RSSFeedSource
	 * @param base_feed_url A String value representing the URL where this resource is located
	 */
	public RSSFeedSource(String unique_name, String base_feed_url) {
		this(unique_name, base_feed_url, TrafficSource.DEFAULT_UPDATE_FREQUENCY_S);
	}

	/**
	 * RSSFeedSource base constructor. 
	 * @param unique_name A unique String value to represent this RSSFeedSource
	 * @param base_feed_url A String value representing the URL where this resource is located	 
	 * @param update_frequency An interval in seconds upon which to update this Source
	 */
	public RSSFeedSource(String unique_name, String base_feed_url,
			int update_frequency) {
		super(unique_name, base_feed_url, update_frequency);
	}

	/**
	 * A hook to do any pre-processing on a traffic update (i.e. strip out extraneous information
	 * before posting. This is called during doCheck before actually constructing a TrafficUpdate.
	 * It should be overrided by subclasses to meet their specific needs.
	 * @param update The text of a TrafficUpdate
	 * @return The processed version of the text
	 */
	@Override
	public String processUpdateData(String update) {
		// TODO Auto-generated method stub
		return update;
	}
	
	/**
	 * Does all the work for checking the XML source, and parsing out individual nodes of the XML tree.
	 * This function relies heavily on calls in the base class to handle network communications and XML
	 * parsing, and calls these functions with the appropriate parameters suitable to an RSS feed.
	 * 
	 * @param updateLastCheck A boolean value to indicate whether or not the lastCheck flag should
	 * be updated to now
	 * @return a list of TrafficUpdates, each update processed by the processUpdateData function.
	 */
	@Override
	public List<TrafficUpdate> doCheck(boolean updateLastCheck)
			throws TrafficSourceException {
	
		ArrayList<TrafficUpdate> updateList = new ArrayList<TrafficUpdate>();
		
		InputStream feed_stream = this.getFeedAsStream(null);
		
		//System.err.println("FEED CONTENTS HERE IS " + feed_stream);
		
		NodeList node_list  = this.getNodes(feed_stream, "/rss/channel/item");
		//System.err.println("Got " + node_list.getLength() + " nodes");
		
		ArrayList<HashMap<String, String>> node_contents = this.getElementsFromNodes(node_list, new String[]{"title","description"});
		
		Iterator<HashMap<String,String>> node_iterator = node_contents.iterator();
		while (node_iterator.hasNext()) {
			HashMap<String, String> h = node_iterator.next();
			
			String processed_update = processUpdateData(h.get("description"));
			//System.err.println("Found (processed) description " + processed_update);
			
			TrafficUpdate t = new TrafficUpdate(this, System.currentTimeMillis(), processed_update);
			updateList.add(t);
		}
		
		if (updateLastCheck) {
			this.setLastCheckToNow();
		}
		
		reconcileNewAndRecentUpdates(updateList);
		
		return updateList;
	}
	
}
